﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace DELVE_GAME.ViewStructure
{
    class GameboardCell : Button
    {
        Tile myTile;
        int tileType;
        int numTileTypes = 9;
        int padding = 1;
        Game game;
        PlayerProfileManager profileManager;
        bool isSelected;
        Color myBackgroundColor;

        public GameboardCell(Game game, PlayerProfileManager profileManager, Tile tile, Sprite sprite, int x, int y)
            : base(x, y, sprite)
        {
            myTile = tile;
            myBackgroundColor = Color.Black;
            tileType = myTile.type;
            this.game = game;
            this.profileManager = profileManager;
            isSelected = false;
        }

        public Game getGame() {
            return this.game;
        }
        public void setSpriteIndex( int index )
        {
            imageIndex = index;
        }

        public override void draw(SpriteBatch sb)
        {
            Blinker.update();
            Color drawBGColor;
            if (isSelected) { drawBGColor = Color.Cornsilk; }
            else { drawBGColor = myBackgroundColor; }
            if (visible)
            {
                if (sprite != null)
                {
                    Color color = getTileColor(myTile);
                    Virus v = this.myTile.getVirus();
                    myBackgroundColor = Color.Black;
                    sprite.draw(sb, this.x * width + offsetX - padding, this.y * height + offsetY - padding, 0, ((double)this.width / sprite.width()), drawBGColor);//(sb, this.x * width + offsetX, this.y * height + offsetY, tileType + (imageIndex * numTileTypes), ((double)this.width - (2 * padding)) / sprite.width(), myBackgroundColor);

                    int xPos = this.x * width + offsetX;
                    int yPos = this.y * height + offsetY;
                    double spriteWidth = ((double)this.width - (2 * padding)) / sprite.width();
                    int tileTypeOffset = imageIndex * numTileTypes; 
                    if (game.tileInTerritory(this.myTile))
                    {
                        this.myBackgroundColor = Color.Red;
                    }
                    if (v == null)
                    {
                        if (game.canPlaceBase(this.myTile))
                        {
                            int currentPlayer = game.getCurrentPlayerIndex();
                            this.myBackgroundColor = profileManager.getPlayerColor(currentPlayer);
                        }


                        sprite.draw(sb, xPos, yPos, tileType + tileTypeOffset, spriteWidth, color);
                    }
                    else if ((Virus.isFriend(game.getCurrentPlayerIndex(), v) || game.isVisible(myTile)) && v.getStats()[5] == 1)
                    {
                        sprite.draw(sb, xPos, yPos, (int)TILE_VARIANTS.NUM_TYPES + tileTypeOffset, spriteWidth, color);
                    }
                    else
                    {
                        sprite.draw(sb, xPos, yPos, tileType + tileTypeOffset, spriteWidth, color);
                    }
                }
            }
        }

        private Color getTileColor(Tile tile)
        {
            Color color = Color.White;
            if (tile.isOccupied())
            {
                color = profileManager.getPlayerColor(tile.getVirus().getPlayerIndex());
                int normalizeFactor = 5;
                double ratio = ((double)tile.getVirus().getViewPotency() + normalizeFactor) / ((double)VIRUS_DEFAULTS.MAX_POTENCY);
                int baseColor = Color.White.R;
                int red = color.R;
                int green = color.G;
                int blue = color.B;
                int diffR = Math.Abs(baseColor - red);
                int diffG = Math.Abs(baseColor - green);
                int diffB = Math.Abs(baseColor - blue);

                double newR = red * ratio + (1 - ratio) * baseColor;
                double newG = green * ratio + (1 - ratio) * baseColor;
                double newB = blue * ratio + (1 - ratio) * baseColor;

                //List<Virus> vlist = new List<Virus>();
                List<Virus> vlist = game.getCurrentPlayer().alertViruses;
                /*if(!vlist.Contains(this.myTile.getVirus()))
                {
                    vlist.Add(this.myTile.getVirus());
                }*/
                if (vlist != null)
                    if (vlist.Contains(this.myTile.getVirus()))
                    {
                        ratio = Blinker.getPercentValue();
                        newR = newR * (1 - ratio) + (ratio) * (baseColor);
                        newG = newG * (1 - ratio) + (ratio);// *baseColor;
                        newB = newB * (1 - ratio) + (ratio);// *baseColor;
                    }

                color = new Color((int)newR, (int)newG, (int)newB);
            }
            if (!game.isVisible(tile))
            {
                color = Color.DarkGray;

            }

            return color;
        }


        public override void setOffset(int x, int y)
        {
            this.offsetX = x;
            this.offsetY = y;
        }

        internal void setWidth(int w)
        {
            this.width = w;
        }

        internal void setHeight(int h)
        {
            this.height = h;
        }

        public override void mouseOver(int x, int y)
        {
            //this.imageIndex += 1;
            //imageIndex %= numTileTypes;
            //Console.WriteLine(tileType);
            //
            if (this.checkCollision(x, y))
            {
                String str = "";
                switch (myTile.type)
                {
                    /*TILE,
    HIGH_BANDWIDTH,
    LOW_BANDWIDTH,
    WIFI,
    BROKEN_LINK,
    BUS,
    FIREWALL,
    DYING_LINK,
                     * 
                     */
                    case 0 :
                        str = "Tile: Plain Tile\nNo bonuses\n";
                        break;
                    case 1:
                        str = "Tile: High Bandwidth\n+2 speed\n";
                        break;
                    case 2:
                        str = "Tile: Low Bandwidth\n-1 speed\n";
                        break;
                    case 3:
                        str = "Tile: Wifi\nConnects to other Wifi tiles.\n";
                        break;
                    case 4:
                        str = "Tile: Broken Link\nViruses cannot expand to this tile.\n";
                        break;
                    case 5:
                        str = "Tile: Bus\nViruses can only enter from the ends\nand expand in the direction of the bus.\n +3 speed while in bus.\n";
                        break;
                    case 6:
                        str = "Tile: Firewall\nViruses cannot enter these tiles\nfrom the indicated direction.\n";
                        break;
                    case 7:
                        str = "Tile: Dying link\nWhile active, these act as normal tiles.\nThey die off a little each turn\nWhen they are dead, they become a Broken Link.";
                        break;
                }
                List<int> stats = this.myTile.getVirusStats();
                if(stats.Count != 0 && game.isVisible(myTile))
                {
                    str += "\nVirus\nSPEED: " + stats[0] +
                    "\nPOTENCY: " + stats[1] +
                    "\nSTATIC POTENCY: " + stats[2] +
                    "\nOUTBREAK: " + (stats[3] == 0 ? "NO" : "YES") +
                    "\nRESILIENCE: " + (stats[4] == 0 ? "NO" : "YES") +
                    "\nBASE: " + (stats[5]==0 ? "NO" : "YES");
                }
                View.setHudText(str);
                View.setHudTileType(myTile.type);
            }

            base.mouseOver(x, y);
            //throw (new NotImplementedException());
        }

        public override void mousePressed(int x, int y)
        {
            if (tileType != (int)TILE_VARIANTS.BROKEN_LINK)
            {
                base.mousePressed(x, y);
            }
        }

        public override void mouseReleased(int x, int y)
        {

        }
        public override bool checkCollision(int x, int y)
        {
            int left = this.x * width + offsetX;
            int top = this.y * height + offsetY;
            int right = left + width;
            int bottom = top + height;
            return (x >= left && y >= top && x < right && y < bottom);
        }

        public void setSelected(bool select)
        {
            isSelected = select;
        }

        public bool getSelected()
        {
            return isSelected;
        }


        internal int getX()
        {
            return x * width + offsetX;
        }

        internal int getY()
        {
            return y * height + offsetY;
        }

        internal Tile getTile()
        {
            return myTile;
        }

        private class Blinker
        {
            private static double value;
            public static double getPercentValue()
            {
                return value;
            }

            public static void update()
            {
                value += 0.0001;
                if (value > 0.750)
                {
                    value = 0.0;
                }
            }
        }
    }
}
